﻿function Window(config, win) {
    var _this = this;
    var _basePosition = 99999;
    var _window = null;
    var _windowFrame = null;
    var _rootPanel = null;
    var _modalPanel = null;
    var _caption = null;
    var _content = null;
    var _closer = null;
    this.$e = function (obj) { return obj ? false : true; };
    this.$alpha = function (obj, opacity) {
        var filter = obj.style.filter;
        obj.style.filter = "Alpha(Opacity=" + opacity + ")";
        obj.style.opacity = opacity / 100;
        obj.filters.alpha.apply();
        obj.filters.alpha.play();
        return filter;
    };
    this.$blendTrans = function (obj, duration) {
        var filter = obj.style.filter;
        obj.style.filter = "blendTrans(Duration=" + duration + ")";
        obj.style.visibility = "hidden";
        obj.filters.blendTrans.apply();
        obj.filters.blendTrans.play();
        obj.style.visibility = "visible";
        return filter;
    };
    this.$gradient = function (obj, startColor, endColor, dir) {
        var filter = obj.style.filter;
        dir = dir || 1;
        obj.style.filter = "progid:DXImageTransform.Microsoft.Gradient(GradientType=" + dir + ", StartColorStr=" + startColor + ", EndColorStr=" + endColor + ")";
        return filter;
    };
    this.$get = function (id, target) {
        if (this.$e(target)) {
            target = win;
        };
        return target.document.getElementById(id);
    };
    this.$create = function (tag, target) {
        if (this.$e(target)) {
            target = win;
        };

        if (window.attachEvent) {
            doc = target.document;
        } else if (window.addEventListener) {
            if (target.toString() == "[object HTMLIFrameElement]") {
                doc = target.contentDocument;
            } else {
                doc = target.document;
            }
        }

        return doc.createElement(tag);
    };
    this.$frame = function (config, target) {
        var frame = this.$create("iframe", target);
        frame.id = config.id ? config.id : "";
        frame.style.position = "absolute";
        frame.style.width = config.width || "100%";
        frame.style.height = config.height || "100%";
        frame.frameBorder = 0;
        frame.scrolling = config.scrolling ? "" : "no";
        return frame;
    };
    this.$getFrame = function (idOrPosition, target) {
        if (this.$e(target)) {
            target = win;
        };
        if (this.$e(idOrPosition)) {
            return target.frames[0];
        } else if (typeof (idOrPosition) === "number") {
            return target.frames[idOrPosition];
        } else if (typeof (idOrPosition) === "string") {
            return target.frames[idOrPosition];
        } else {
            return null;
        }
    };
    this.$icon = function (config, target) {
        var container = this.$create("a", target);
        container.margin = config.margin || 2;
        container.margin = container.margin
        container.style.position = "absolute";
        var icon = this.$create("img", target);
        this.$add(icon, container);
        icon.src = config.icon;
        icon.style.width = config.iconWidth || 16;
        icon.style.height = config.iconHeight || 16;
        icon.border = 0;
        if (!this.$e(config.width)) { container.style.width = config.width; };
        if (!this.$e(config.height)) { container.style.height = config.height; };
        if (!this.$e(config.x)) { container.style.left = config.x; };
        if (!this.$e(config.y)) { container.style.top = config.y; };

        if (window.attachEvent) {
            container.attachEvent("onmousedown", function () {
                target.event.cancelBubble = target.event.srcElement === icon;
            });
            container.attachEvent("onmouseup", function () {
                target.event.cancelBubble = true;
                if (!_this.$e(config.click)) {
                    config.click();
                }
            });
            container.attachEvent("ondblclick", function () {
                target.event.cancelBubble = true;
                var fromIcon = target.event.srcElement === icon;
                if (fromIcon && !_this.$e(config.doubleClick)) {
                    config.doubleClick();
                }
            });
            if (config.useEffect === true) {
                var _over = false;
                container.attachEvent("onmouseover", function () {
                    if (_over === false) {
                        _over = true;
                        setTimeout(function () {
                            _over = false;
                        }, 1000);
                        // _this.$blendTrans(icon, 1);
                    }
                });
            };
        } else if (window.addEventListener) {
            container.addEventListener("mousedown", function (event) {
                event.target === icon;
            }, false);
            container.addEventListener("mouseup", function (event) {
                if (!_this.$e(config.click)) {
                    config.click();
                }
            }, false);
            container.addEventListener("dblclick", function (event) {
                var fromIcon = event.target === icon;
                if (fromIcon && !_this.$e(config.doubleClick)) {
                    config.doubleClick();
                }
            }, false);
            if (config.useEffect === true) {
                var _over = false;
                container.addEventListener("mouseover", function () {
                    if (_over === false) {
                        _over = true;
                        setTimeout(function () {
                            _over = false;
                        }, 1000);
                        //_this.$blendTrans(icon, 1);
                    }
                }, false);
            };
        }

        if (!this.$e(config.text)) {
            icon.align = config.align || "left";
            container.innerHTML += config.text;
        };
        if (!this.$e(config.tip)) {
            icon.title = config.tip;
        };
        return container;
    };
    this.$add = function (obj, parent) {
        parent.appendChild(obj);
    };
    this.$config = function (config) {
        if (this.$e(config)) config = {};
        if (this.$e(config.id)) config.id = _this.getDefaultId();
        if (this.$e(config.width)) {
            config.width = 320;
        }
        else if (config.width.toString().indexOf('%') != -1) {
            config.width = parseInt(win.document.body.clientWidth * parseFloat(config.width) / 100) || 320;
        };
        if (this.$e(config.height)) {
            config.height = 260;
        } else if (config.height.toString().indexOf('%') != -1) {
            config.height = parseInt(win.document.body.clientHeight * parseFloat(config.height) / 100) || 260;
        };
        if (this.$e(config.caption)) config.caption = win.document.title;
        if (this.$e(config.modal)) config.modal = false;
        if (this.$e(config.modalOpacity)) config.modalOpacity = window_modal_opacity;
        if (this.$e(config.modalColor)) config.modalColor = window_modal_bgcolor;
        if (this.$e(config.html)) config.html = "";
        if (this.$e(config.src)) config.src = "";
        if (this.$e(config.contentCssClass)) config.contentCssClass = "";
        if (this.$e(config.contentScrollable)) config.contentScrollable = false;
        if (this.$e(config.visible)) config.visible = false;
        if (this.$e(config.movable)) config.movable = true;
        if (this.$e(config.closable)) config.closable = config.closable === false ? false : true;
        if (this.$e(config.position)) config.position = "middle-center";
        if (this.$e(config.closeTip)) config.closeTip = window_close_tip;
        if (this.$e(config.closeIcon)) config.closeIcon = window_close_image;
        if (this.$e(config.closeHoverIcon)) config.closeHoverIcon = window_close_image_hover;
        if (this.$e(config.closeAction)) config.closeAction = "hideOnClose";
        if (this.$e(config.icon)) config.icon = window_icon;
        if (this.$e(config.showCaption)) config.showCaption = true;
        if (this.$e(config.borderSize)) config.borderSize = window_border_size;
        if (this.$e(config.borderColor)) config.borderColor = window_border_color;
        if (this.$e(config.captionHeight)) config.captionHeight = window_caption_height;
        if (this.$e(config.clipInBody)) config.clipInBody = true;
        if (this.$e(config.blendTrans)) config.blendTrans = 0;
        return config;
    };

    this.getDefaultId = function () {
        return "Window_UnNamed_" + this.getSystemWindows().length;
    };
    this.getSystemWindows = function () {
        if (this.$e(win.SKSystemWindows)) {
            win.SKSystemWindows = [];
        };
        return win.SKSystemWindows;
    };
    this.getFocusWindow = function () {
        var focus = this;
        var windows = this.getSystemWindows();
        for (var i in windows) {
            if (windows[i].getZPosition() > focus.getZPosition()) {
                focus = windows[i];
            }
        };
        return focus;
    };
    this.setFocusWindow = function (window) {
        if (this.$e(window)) { window = this; };
        var focus = this.getFocusWindow();
        if (focus !== this) {
            var pos = focus.getZPosition() + 1;
            this.setZPosition(pos);
        }
    };
    this.getPositionByString = function (pos) {
        var ret = { x: 0, y: 0 };
        if (this.$e(pos)) { return ret; };
        var size = this.getSize();
        if (pos.indexOf("left") !== -1) { ret.x = 0; }
        else if (pos.indexOf("center") !== -1) {
            ret.x = win.document.body.scrollLeft + (win.document.body.offsetWidth - size.width) / 2;
        } else if (pos.indexOf("right") !== -1) {
            ret.x = win.document.body.offsetWidth - size.width;
        };
        if (pos.indexOf("top") !== -1) {
            ret.y = 0;
        } else if (pos.indexOf("middle") !== -1) {
            ret.y = win.document.body.scrollTop + (win.document.body.clientHeight - size.height) / 2;
        } else if (pos.indexOf("bottom") !== -1) {
            ret.y = win.document.body.clientHeight - size.height;
        };
        ret.x = ret.x ? (ret.x < 0 ? 0 : ret.x) : 0;
        ret.y = ret.y ? (ret.y < 0 ? 0 : ret.y) : 0;
        return ret;
    };
    this.setCaptionText = function (caption) {
        _caption.firstChild.lastChild.nodeValue = caption;
    };
    this.setContentUrl = function (url) {
        _content.src = url;
    };
    this.getContentUrl = function (url) {
        return _content.src;
    };
    this.setPosition = function (position) {
        if (typeof (position) === "undefined") {
            position = "middle-center";
        };
        if (typeof (position) === "string") {
            position = this.getPositionByString(position);
        };
        _window.style.left = position.x;
        _window.style.top = position.y;
    };
    this.getZPosition = function () {
        return parseInt(_window.style.zIndex);
    };
    this.setZPosition = function (position) {
        _window.style.zIndex = position;
    };
    this.isVisible = function () {
        return _window.style.display !== "none";
    };
    this.setVisible = function (visible) {
        if (!_created && !visible) {
            return;
        } else if (visible && !_created) {
            doCreate();
        };

        if (visible) {
            _window.style.display = "";
            if (this.isModal()) {
                _modalPanel.style.display = "";
            };
            if (config.blendTrans > 0) {
                //this.$blendTrans(_window, config.blendTrans);
                try {
                    //_modalPanel.style.filter = this.$blendTrans(_modalPanel, config.blendTrans);
                } catch (e) { }
            };
            _windowFrame.outerWindow = this;
        } else {
            _window.style.display = "none";
            if (this.isModal()) {
                _modalPanel.style.display = "none";
            };
        }
    };
    this.isModal = function () {
        return config.modal;
    };
    this.getConfig = function () {
        return config;
    };
    this.getCloserImage = function () {
        return _closer.childNodes[0];
    }; this.getWindow = function () {
        return _window;
    };
    this.dispose = function () {
        try {
            _modalPanel.removeNode(true);
        } catch (e) {
        };
        this.releaseFrame(this.getWindowFrame());
        _window.parentNode.removeChild(_window);
        _windowFrame = null;
        _window = null;
        _closer = null;
        _caption = null;
        _content = null;
    };
    this.releaseFrame = function (frame) {
        if (frame) {
            var len = frame.document.frames.length;
            for (var i = 0; i < len; i++) {
                this.releaseFrame(frame.document.frames[i]);
            };
            for (var i = 0; i < frame.document.all.length; i++) {
                frame.document.all[i].removeNode(true);
            };
            frame.src = "javascript: false;";
        }
    };
    this.close = function () {
        if (config.closeAction === "hideOnClose") {
            this.setVisible(false);
        } else {
            this.dispose();
        }
    };
    this.getWindowFrame = function () {
        if (this.$e(_windowFrame)) {
            _windowFrame = this.$getFrame(config.id, win);
        };
        return _windowFrame;
    };
    this.getRootPanel = function () {
        return _rootPanel;
    };
    this.getCaption = function () {
        return _caption;
    };
    this.getSize = function () {
        var size = { width: NaN, height: NaN };
        if (this.$e(_window)) {
            _window = this.$get(config.id);
        };
        size.width = _window.clientWidth === 0 ? config.width : _window.clientWidth;
        size.height = _window.clientHeight === 0 ? config.height : _window.clientHeight;
        return size;
    };
    this.setSize = function (size) {
        if (!isNaN(size.width) && size.width >= 0) {
            _window.style.width = size.width;
            _caption.style.width = size.width - config.borderSize * 2;
            var cap = _caption.childNodes[0];
            var width = size.width - 4 * config.borderSize;
            //if (config.closable) {
            cap.style.width = width - config.captionHeight;
            _closer.style.left = width - config.captionHeight + config.borderSize;
            //} else {
            //    cap.style.width = width;
            //}
        };
        if (!isNaN(size.height) && size.height >= 0) {
            _window.style.height = size.height;
            var height = size.height - _caption.clientHeight - config.borderSize * 2;
            if (height >= 0) {
                _content.style.height = height;
            }
        };
    };
    this.getModalPanel = function () {
        return _modalPanel;
    };
    this.adjustBound = function () {
        this.setPosition(config.position);
    };
    this.createRootPanel = function () {
        var frame = this.getWindowFrame();
        frame.oncontextmenu = function () {
            return false;
        };
        var rootPanel = this.$create("div", frame);
        rootPanel.style.position = "absolute";
        rootPanel.style.width = "100%";
        rootPanel.style.height = "100%";

        var margin = 0;
        if (window.addEventListener) {
            margin = -8;
        }
        rootPanel.style.margin = margin;

        rootPanel.style.backgroundColor = config.borderColor;

        if (window.attachEvent) {
            this.$add(rootPanel, frame.document);
        } else if (window.addEventListener) {
            if (frame.toString() == "[object HTMLIFrameElement]") {
                this.$add(rootPanel, frame.contentDocument.body);
            } else {
                this.$add(rootPanel, frame.document.body);
            }
        }

        return rootPanel;
    };
    this.createModalPanel = function () {
        var modalPanel = this.$create("iframe");
        modalPanel.style.position = "absolute";
        modalPanel.style.width = "100%";
        modalPanel.style.height = "100%";
        modalPanel.style.filter = "Alpha(Opacity=" + config.modalOpacity + ")";
        modalPanel.style.opacity = config.modalOpacity / 100;
        modalPanel.style.backgroundColor = "white";
        modalPanel.style.left = 0;
        modalPanel.style.top = 0;
        this.$add(modalPanel, win.document.body);
        var content = this.$create("div", modalPanel.contentWindow);
        return modalPanel;
    };

    this.createCaption = function () {
        var frame = this.getWindowFrame();
        var caption = this.$create("div", frame);

        var margin = 0;
        if (window.addEventListener) {
            margin = -8;
        }

        caption.style.padding = (config.captionHeight - 14 + margin) / 2;
        caption.style.position = "absolute";
        caption.style.width = config.width - 2 * config.borderSize;
        caption.style.height = config.captionHeight;
        caption.style.margin = config.borderSize;
        caption.style.marginBottom = 0;
        caption.style.visible = config.showCaption;
        caption.style.fontSize = 12;
        caption.style.fontWeight = "bold";
        //this.$gradient(caption, window_caption_bgcolor_begin, window_caption_bgcolor_end);

        if (config.movable) {
            var currentPosition = null;
            var cursorPos = null;
            var captionFilter = null;

            caption.onmousedown = function (event) {
                var event = event || frame.event;
                if (event.button === 0 || event.button === 1) {
                    currentPosition = {
                        x: _window.offsetLeft, y: _window.offsetTop
                    };

                    caption.style.cursor = window_caption_cursor_move;

                    if (!window.captureEvents) {
                        cursorPos = {
                            x: event.x, y: event.y
                        };
                        caption.setCapture();
                    } else {
                        cursorPos = {
                            x: _window.offsetLeft + event.x, y: _window.offsetTop + event.y
                        };
                        window.captureEvents(Event.MOUSEMOVE | Event.MOUSEUP);
                    }
                }
                event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true);
            };
            caption.onmousemove = function (event) {
                var event = event || frame.event;
                if (cursorPos !== null) {
                    var offset = null;

                    if (!window.captureEvents) {
                        offset = { x: event.x - cursorPos.x, y: event.y - cursorPos.y };
                    } else {
                        offset = { x: _window.offsetLeft + event.x - cursorPos.x, y: _window.offsetTop + event.y - cursorPos.y };
                    }

                    var size = _this.getSize();
                    var max = {
                        width: win.document.body.offsetWidth - parseInt(size.width), height: win.document.body.offsetHeight - parseInt(size.height)
                    };
                    var newPos = { x: currentPosition.x + offset.x, y: currentPosition.y + offset.y };
                    if (config.clipInBody) {
                        newPos.y = newPos.y < 0 ? 0 : newPos.y < max.height ? newPos.y : max.height;
                        newPos.x = newPos.x < 0 ? 0 : newPos.x < max.width ? newPos.x : max.width;
                    };
                    _window.style.top = newPos.y;
                    _window.style.left = newPos.x;
                }
            };
            caption.onmouseup = function (event) {
                var event = event || frame.event;
                cursorPos = null;
                caption.style.cursor = window_caption_cursor_normal;

                if (!window.captureEvents) {
                    caption.releaseCapture();
                } else {
                    window.releaseEvents(Event.MOUSEMOVE | Event.MOUSEUP);
                }

                event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true);
            };
        };
        var iconWidth = config.width - 4 * config.borderSize - config.captionHeight;
        if (!this.$e(config.icon)) {
            var icon = this.$icon({ icon: config.icon, align: "left", text: config.caption, width: iconWidth }, frame);
            this.$add(icon, caption);
        };
        if (!this.$e(config.closeIcon)) {
            if (config.closable) {
                _closer = this.$icon({ icon: config.closeIcon, click: function () { _this.close(); }, useEffect: true, x: iconWidth + config.borderSize, y: config.borderSize, tip: config.closeTip }, frame);
                _closer.style.cursor = "pointer";

                _closer.onmouseover = function () {
                    _closer.firstChild.src = config.closeHoverIcon;
                };

                _closer.onmouseout = function () {
                    _closer.firstChild.src = config.closeIcon;
                };
                this.$add(_closer, caption);
            } else {
                _closer = this.$icon({ icon: config.closeIcon, click: function () { _this.close(); }, useEffect: true, x: 92 + config.borderSize, y: config.borderSize, tip: config.closeTip }, frame);
                _closer.style.cursor = "pointer";

                this.$add(_closer, caption);
            };
        };

        this.$add(caption, _rootPanel);
        return caption;
    };

    this.createContent = function () {
        var frame = this.getWindowFrame();
        var _width = config.width - 2 * config.borderSize;
        var _height = config.height - 2 * config.borderSize;
        if (config.showCaption) {
            _height -= config.captionHeight;
        };
        var contentTag = this.$frame({ id: config.id + "Content", width: _width, height: _height }, frame);
        contentTag.scrolling = config.contentScrollable ? "auto" : "no";
        contentTag.style.left = config.borderSize;
        contentTag.style.top = config.height - _height - config.borderSize;
        this.$add(contentTag, _rootPanel);
        if (config.src) {
            contentTag.src = config.src;
        } else if (config.html) {
            var frame = this.$getFrame(0, this.getWindowFrame());
            var panel = this.$create("div", frame);
            panel.className = config.contentCssClass;
            panel.style.position = "absolute";
            panel.style.width = "100%";
            panel.style.height = "100%";
            panel.style.margin = 0;
            panel.innerHTML = config.html;
            this.$add(panel, frame.document);
        } else {
            alert("请配置src或html!");
        };
        return contentTag;
    };

    this.createWindow = function () {
        var frameTag = this.$frame(config);
        frameTag.style.zIndex = this.isModal() ? _basePosition : 999;

        this.$add(frameTag, win.document.body);

        if (config.modal) {
            _modalPanel = this.createModalPanel();
        };

        if (window.addEventListener) {
            frameTag.onload = function () {
                _rootPanel = _this.createRootPanel();
                _caption = _this.createCaption();
                _content = _this.createContent();
            };
        };

        _rootPanel = this.createRootPanel();
        _caption = this.createCaption();
        _content = this.createContent();
        _content.contentWindow.outerWindow = this;
        return frameTag;
    };

    var _created = false;
    var _this = this;
    function doCreate() {
        if (_this.$e(win)) {
            win = self;
        };
        config = _this.$config(config);
        _window = _this.createWindow();
        _created = true;
        _this.setVisible(config.visible);
        _this.setPosition(config.position);

        if (window.attachEvent) {
            window.attachEvent("onresize", function () {
                _this.adjustBound();
            });
        } else if (window.addEventListener) {
            window.addEventListener("resize", function () {
                _this.adjustBound();
            }, false);
        }
    };
    this.setUrl = function (url) {
        config.src = url;
        _content.src = url;
    };
    this.getUrl = function () {
        return config.src;
    };
    if (!config.createOnFirstVisible) {
        doCreate();
    };
};